﻿
#ifdef _DEBUG

#include <boost/assert.hpp>
#include <iostream>
#include <iterator>
#include <fstream>
#include <sstream>

#include "kodes.h"

using namespace std;


void rut_tests()
{
  char testDataXSys[] =   "Aa Bb Cc Cxcx Dd Ee Ff Gg Gxgx H h Hxhx Ii Jj Jxjx Kk Ll Mm Nn Oo Pp Rr Ss Sxsx Tt Uu Uxux Vv Zz";
  char testDataHSys[] =   "Aa Bb Cc Chch Dd Ee Ff Gg Ghgh H h Hhhh Ii Jj Jhjh Kk Ll Mm Nn Oo Pp Rr Ss Shsh Tt Uu Uu Vv Zz";
  char testDataLatin3[] = "Aa Bb Cc \xC6\xE6 Dd Ee Ff Gg \xD8\xF8 H h \xA6\xB6 Ii Jj \xAC\xBC Kk Ll Mm Nn Oo Pp Rr Ss \xDE\xFE Tt Uu \xDD\xFD Vv Zz";
  unsigned char testDataUtf8Raw[] = {                      0x41, 0x61, 0x20, 0x42, 0x62, 0x20, 0x43, 0x63, 0x20, 0xC4, 0x88, 0xC4, 0x89, 0x20, 0x44, 0x64, 0x20, 0x45, 0x65, 0x20, 0x46, 0x66, 0x20, 0x47, 0x67, 0x20, 0xC4, 0x9C, 0xC4, 0x9D, 0x20, 0x48, 0x20, 0x68, 0x20, 0xC4, 0xA4, 0xC4, 0xA5, 0x20, 0x49, 0x69, 0x20, 0x4A, 0x6A, 0x20, 0xC4, 0xB4, 0xC4, 0xB5, 0x20, 0x4B, 0x6B, 0x20, 0x4C, 0x6C, 0x20, 0x4D, 0x6D, 0x20, 0x4E, 0x6E, 0x20, 0x4F, 0x6F, 0x20, 0x50, 0x70, 0x20, 0x52, 0x72, 0x20, 0x53, 0x73, 0x20, 0xC5, 0x9C, 0xC5, 0x9D, 0x20, 0x54, 0x74, 0x20, 0x55, 0x75, 0x20, 0xC5, 0xAC, 0xC5, 0xAD, 0x20, 0x56, 0x76, 0x20, 0x5A, 0x7A, 0, 0};
  unsigned char testDataUtf8bomRaw[] = { 0xEF, 0xBB, 0xBF, 0x41, 0x61, 0x20, 0x42, 0x62, 0x20, 0x43, 0x63, 0x20, 0xC4, 0x88, 0xC4, 0x89, 0x20, 0x44, 0x64, 0x20, 0x45, 0x65, 0x20, 0x46, 0x66, 0x20, 0x47, 0x67, 0x20, 0xC4, 0x9C, 0xC4, 0x9D, 0x20, 0x48, 0x20, 0x68, 0x20, 0xC4, 0xA4, 0xC4, 0xA5, 0x20, 0x49, 0x69, 0x20, 0x4A, 0x6A, 0x20, 0xC4, 0xB4, 0xC4, 0xB5, 0x20, 0x4B, 0x6B, 0x20, 0x4C, 0x6C, 0x20, 0x4D, 0x6D, 0x20, 0x4E, 0x6E, 0x20, 0x4F, 0x6F, 0x20, 0x50, 0x70, 0x20, 0x52, 0x72, 0x20, 0x53, 0x73, 0x20, 0xC5, 0x9C, 0xC5, 0x9D, 0x20, 0x54, 0x74, 0x20, 0x55, 0x75, 0x20, 0xC5, 0xAC, 0xC5, 0xAD, 0x20, 0x56, 0x76, 0x20, 0x5A, 0x7A, 0, 0};
  unsigned char testDataUtf16Raw[] = {                0x41, 0x00, 0x61, 0x00, 0x20, 0x00, 0x42, 0x00, 0x62, 0x00, 0x20, 0x00, 0x43, 0x00, 0x63, 0x00, 0x20, 0x00, 0x08, 0x01, 0x09, 0x01, 0x20, 0x00, 0x44, 0x00, 0x64, 0x00, 0x20, 0x00, 0x45, 0x00, 0x65, 0x00, 0x20, 0x00, 0x46, 0x00, 0x66, 0x00, 0x20, 0x00, 0x47, 0x00, 0x67, 0x00, 0x20, 0x00, 0x1C, 0x01, 0x1D, 0x01, 0x20, 0x00, 0x48, 0x00, 0x20, 0x00, 0x68, 0x00, 0x20, 0x00, 0x24, 0x01, 0x25, 0x01, 0x20, 0x00, 0x49, 0x00, 0x69, 0x00, 0x20, 0x00, 0x4A, 0x00, 0x6A, 0x00, 0x20, 0x00, 0x34, 0x01, 0x35, 0x01, 0x20, 0x00, 0x4B, 0x00, 0x6B, 0x00, 0x20, 0x00, 0x4C, 0x00, 0x6C, 0x00, 0x20, 0x00, 0x4D, 0x00, 0x6D, 0x00, 0x20, 0x00, 0x4E, 0x00, 0x6E, 0x00, 0x20, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x20, 0x00, 0x50, 0x00, 0x70, 0x00, 0x20, 0x00, 0x52, 0x00, 0x72, 0x00, 0x20, 0x00, 0x53, 0x00, 0x73, 0x00, 0x20, 0x00, 0x5C, 0x01, 0x5D, 0x01, 0x20, 0x00, 0x54, 0x00, 0x74, 0x00, 0x20, 0x00, 0x55, 0x00, 0x75, 0x00, 0x20, 0x00, 0x6C, 0x01, 0x6D, 0x01, 0x20, 0x00, 0x56, 0x00, 0x76, 0x00, 0x20, 0x00, 0x5A, 0x00, 0x7A, 0x00, 0, 0};
  unsigned char testDataUtf16bomRaw[] = { 0xFF, 0xFE, 0x41, 0x00, 0x61, 0x00, 0x20, 0x00, 0x42, 0x00, 0x62, 0x00, 0x20, 0x00, 0x43, 0x00, 0x63, 0x00, 0x20, 0x00, 0x08, 0x01, 0x09, 0x01, 0x20, 0x00, 0x44, 0x00, 0x64, 0x00, 0x20, 0x00, 0x45, 0x00, 0x65, 0x00, 0x20, 0x00, 0x46, 0x00, 0x66, 0x00, 0x20, 0x00, 0x47, 0x00, 0x67, 0x00, 0x20, 0x00, 0x1C, 0x01, 0x1D, 0x01, 0x20, 0x00, 0x48, 0x00, 0x20, 0x00, 0x68, 0x00, 0x20, 0x00, 0x24, 0x01, 0x25, 0x01, 0x20, 0x00, 0x49, 0x00, 0x69, 0x00, 0x20, 0x00, 0x4A, 0x00, 0x6A, 0x00, 0x20, 0x00, 0x34, 0x01, 0x35, 0x01, 0x20, 0x00, 0x4B, 0x00, 0x6B, 0x00, 0x20, 0x00, 0x4C, 0x00, 0x6C, 0x00, 0x20, 0x00, 0x4D, 0x00, 0x6D, 0x00, 0x20, 0x00, 0x4E, 0x00, 0x6E, 0x00, 0x20, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x20, 0x00, 0x50, 0x00, 0x70, 0x00, 0x20, 0x00, 0x52, 0x00, 0x72, 0x00, 0x20, 0x00, 0x53, 0x00, 0x73, 0x00, 0x20, 0x00, 0x5C, 0x01, 0x5D, 0x01, 0x20, 0x00, 0x54, 0x00, 0x74, 0x00, 0x20, 0x00, 0x55, 0x00, 0x75, 0x00, 0x20, 0x00, 0x6C, 0x01, 0x6D, 0x01, 0x20, 0x00, 0x56, 0x00, 0x76, 0x00, 0x20, 0x00, 0x5A, 0x00, 0x7A, 0x00, 0, 0};

  wchar_t testDataUtf16[] = L"Aa Bb Cc \x0108\x0109 Dd Ee Ff Gg \x011C\x011D H h \x0124\x0125 Ii Jj \x0134\x0135 Kk Ll Mm Nn Oo Pp Rr Ss \x015C\x015D Tt Uu \x016C\x016D Vv Zz";



  LegoKonverto *lk1 = LegoKonverto::getBySignaro(S_X_SYS);
  LegoKonverto *lk2 = LegoKonverto::getBySignaro(S_LATIN3);
  LegoKonverto *lk3 = LegoKonverto::getBySignaro(S_UTF8);
  LegoKonverto *lk4 = LegoKonverto::getBySignaro(S_UTF8);
  LegoKonverto *lk5 = LegoKonverto::getBySignaro(S_UTF16);
  LegoKonverto *lk6 = LegoKonverto::getBySignaro(S_UTF16);
  LegoKonverto *lk7 = LegoKonverto::getBySignaro(S_H_SYS);
  BOOST_ASSERT(lk1);
  BOOST_ASSERT(lk2);
  BOOST_ASSERT(lk3);
  BOOST_ASSERT(lk4);
  BOOST_ASSERT(lk5);
  BOOST_ASSERT(lk6);
  BOOST_ASSERT(lk7);

  ScriboKonverto *sk1 = ScriboKonverto::getBySignaro(S_X_SYS);
  ScriboKonverto *sk2 = ScriboKonverto::getBySignaro(S_LATIN3);
  ScriboKonverto *sk3 = ScriboKonverto::getBySignaro(S_UTF8);
  ScriboKonverto *sk4 = ScriboKonverto::getBySignaro(S_UTF8);
  ScriboKonverto *sk5 = ScriboKonverto::getBySignaro(S_UTF16);
  ScriboKonverto *sk6 = ScriboKonverto::getBySignaro(S_UTF16);
  ScriboKonverto *sk7 = ScriboKonverto::getBySignaro(S_H_SYS);
  BOOST_ASSERT(sk1);
  BOOST_ASSERT(sk2);
  BOOST_ASSERT(sk3);
  BOOST_ASSERT(sk4);
  BOOST_ASSERT(sk5);
  BOOST_ASSERT(sk6);
  BOOST_ASSERT(sk7);

  istringstream iss1(testDataXSys);
  istringstream iss2(testDataLatin3);
  istringstream iss3((char*)testDataUtf8bomRaw);
  istringstream iss4((char*)testDataUtf8Raw);

  std::string s1;
  for (size_t i=0; i<sizeof(testDataUtf16bomRaw)/sizeof(*testDataUtf16bomRaw); i++)
    s1.push_back(testDataUtf16bomRaw[i]);
  istringstream iss5(s1);
  BOOST_ASSERT(iss5.str().size() == sizeof(testDataUtf16bomRaw)/sizeof(*testDataUtf16bomRaw));

  std::string s2;
  for (size_t i=0; i<sizeof(testDataUtf16Raw)/sizeof(*testDataUtf16Raw); i++)
    s2.push_back(testDataUtf16Raw[i]);
  istringstream iss6(s2);

  istringstream iss7(testDataHSys);


  lk1->setStream(&iss1);
  lk2->setStream(&iss2);
  lk3->setStream(&iss3);
  lk4->setStream(&iss4);
  lk5->setStream(&iss5);
  lk6->setStream(&iss6);
  lk7->setStream(&iss7);


  ostringstream oss1;
  ostringstream oss2;
  ostringstream oss3;
  ostringstream oss4;
  ostringstream oss5;
  ostringstream oss6;
  ostringstream oss7;
  sk4->writeBom(true);
  sk6->writeBom(true);
  sk1->setStream(&oss1);
  sk2->setStream(&oss2);
  sk3->setStream(&oss3);
  sk4->setStream(&oss4);
  sk5->setStream(&oss5);
  sk6->setStream(&oss6);
  sk7->setStream(&oss7);

  for (size_t i=0; ; i++)
  {
    wchar_t c1 = lk1->doni();
    wchar_t c2 = lk2->doni();
    wchar_t c3 = lk3->doni();
    wchar_t c4 = lk4->doni();
    wchar_t c5 = lk5->doni();
    wchar_t c6 = lk6->doni();
    wchar_t c7 = lk7->doni();
    BOOST_ASSERT (c1 == c2 && c2 == c3 && c3 == c4 && c4 == c5 && c5 == c6);
    BOOST_ASSERT (c1 == testDataUtf16[i] );

    // por x-sistemo ne kontroli Ŭ kaj ŭ
    BOOST_ASSERT (c1 == L'\x16c' || c1 == L'\x16d' || c1 == c7);
    if (!c1)
      break;
    sk1->meti(c1);
    sk2->meti(c1);
    sk3->meti(c1);
    sk4->meti(c1);
    sk5->meti(c1);
    sk6->meti(c1);
    sk7->meti(c1);
  }

//#define CMP_STRING_KAJ_ARRAY(arr, str) { \
//  for (size_t i=0; i<sizeof(arr)/sizeof(*arr); i++) { \
//  BOOST_ASSERT(str[i] == arr[i]); } }

  for (size_t i=0; i<sizeof(testDataXSys)/sizeof(*testDataXSys)-1; i++)
  {
    BOOST_ASSERT(oss1.str()[i] == testDataXSys[i] || 
      ((oss1.str()[i] == 'x' || oss1.str()[i] == 'X') && (testDataXSys[i] == 'x' || testDataXSys[i] == 'X'))); 
  }

  for (size_t i=0; i<sizeof(testDataLatin3)/sizeof(*testDataLatin3)-1; i++)
  {
    BOOST_ASSERT(oss2.str()[i] == testDataLatin3[i]); 
  }

  for (size_t i=0; i<sizeof(testDataUtf8Raw)/sizeof(*testDataUtf8Raw)-2; i++)
  {
    BOOST_ASSERT((unsigned char)oss3.str()[i] == testDataUtf8Raw[i]); 
  }

  for (size_t i=0; i<sizeof(testDataUtf8bomRaw)/sizeof(*testDataUtf8bomRaw)-2; i++)
  {
    BOOST_ASSERT((unsigned char)oss4.str()[i] == testDataUtf8bomRaw[i]); 
  }

  for (size_t i=0; i<sizeof(testDataUtf16Raw)/sizeof(*testDataUtf16Raw)-2; i++)
  {
    BOOST_ASSERT((unsigned char)oss5.str()[i] == testDataUtf16Raw[i]); 
  }

  for (size_t i=0; i<sizeof(testDataUtf16bomRaw)/sizeof(*testDataUtf16bomRaw)-2; i++)
  {
    BOOST_ASSERT((unsigned char)oss6.str()[i] == testDataUtf16bomRaw[i]); 
  }

  for (size_t i=0; i<sizeof(testDataHSys)/sizeof(*testDataHSys)-1; i++)
  {
    BOOST_ASSERT(oss7.str()[i] == testDataHSys[i] || 
      ((oss7.str()[i] == 'h' || oss7.str()[i] == 'H') && (testDataHSys[i] == 'h' || testDataHSys[i] == 'H'))); 
  }

  delete lk1;
  delete lk2;
  delete lk3;
  delete lk4;
  delete lk5;
  delete lk6;
  delete lk7;

  delete sk1;
  delete sk2;
  delete sk3;
  delete sk4;
  delete sk5;
  delete sk6;
  delete sk7;

}

#endif
